package game.controlling;
import java.util.Vector;

import network.NetworkController;
import network.byteConversions.ByteConverter;
import network.dataFormats.NetworkPackage;
import network.dataFormats.PackageType;
/**
 * Provides methods for creating and reading packages that contain controller-data. Converts strings like "jump", "walkLeft", ... in arbitrary integers and converts them back which saves some amount of data traffic.
 * 
 * @author toni
 * 
 */
public class ControlData {
	private static final int INVALID = -1;
	private static Vector<String> identifiers;
	private static int MAX = 8;
	public ControlData(Vector<String> identifiers) {
		ControlData.identifiers = identifiers;
	}
	public static NetworkPackage create(LocalController localController, int clientId, int packageId, float time) {
		int numBytes = MAX * 4 + 4 + 8; // 4 bytes for each pressed button, 4
										// for the id and 8 for the mouse
										// position
		byte[] data = new byte[numBytes];
		ByteConverter.intToFourBytes(clientId, data, 0);
		ByteConverter.floatToFourBytes(localController.getMp().x, data, 4);
		ByteConverter.floatToFourBytes(localController.getMp().y, data, 8);
		// New commands / Removed commands
		Vector<String> touchedCommands = new Vector<String>();
		for (int k : localController.keyListener.buttons) {
			String s = localController.getString(k);
			if (s == null)
				continue;
			touchedCommands.add(s);
		}
		for (int k : localController.keyListener.keys) {
			String s = localController.getString(k);
			if (s == null)
				continue;
			touchedCommands.add(s);
		}
		writeCommands(localController, data, touchedCommands, 12);
		return new NetworkPackage(PackageType.CONTROL, data, packageId, time);
	}
	private static void writeCommands(LocalController localController, byte[] data, Vector<String> commands, int offset) {
		for (int i = 0; i < MAX; i++) {
			int conversionIndex;
			if (commands.size() <= i) { // All commands written, write INVALID
										// commands
				conversionIndex = INVALID;
			}
			else {
				String identifier = localController.getIdentifier(commands.get(i));
				conversionIndex = identifiers.indexOf(identifier); // Strings
																	// are too
																	// big to
																	// send,
																	// convert
																	// into ints
			}
			ByteConverter.intToFourBytes(conversionIndex, data, offset + 4 * i);
		}
	}
	public static void read(NetworkController controller, NetworkPackage p) {
		byte[] data = p.getData();
		controller.setMp(ByteConverter.bytesToPoint(data, 4));
		// Read added commands
		controller.keys.clear();
		controller.buttons.clear();
		for (int i = 0; i < MAX; i++) {
			int conversionIndex = ByteConverter.bytesToInt(data, 12 + 4 * i);
			if (conversionIndex == INVALID)
				continue;
			String identifier = identifiers.get(conversionIndex);
			controller.addTouchedKey(identifier);
		}
	}
}
